import Vue,{VNode,PropOptions} from 'vue';
import 'tippy.js/animations/perspective.css';
import Icon from '../icon';
import Tippy from '../tippy';
import {Props} from 'tippy.js';
import Button,{ButtonType} from '../button';
import {PlainObject,AppendTo,StandardOption} from '../../../../types';
/**
 * 触发方式
 */
export type triggerType='click'|'mouseenter';
/**
 * 按钮组
 * @author 蒋光跃
 * @date 2021/6/16
 * 属性----------------------
 * :drop-down		下拉模式, boolean
 * :type			按钮类型, ButtonType
 * :vertical		垂直排列(drop-down必须为false), boolean
 * :outline			线条模式, boolean
 * :rounded			圆角(drop-down必须为false), boolean
 * :split			分割模式, boolean
 * :options			选项, Array<PlainObject>
 * :option-value	方法属性, string
 * :option-label	显示属性, string
 * :disable			禁用, boolean
 * :disable-click	split模式下, 禁止点击, boolean
 * :append-to		下拉框绑定位置, AppendTo
 * :trigger			触发方式, triggerType
 * :custom			完全自定义按钮, boolean
 * 事件----------------------
 * @click			split模式下, 点击按钮部分
 * @option-click	点击选项, PlainObject
 * 插槽----------------------
 * #default			按钮组内容
 * #option			选项插槽
 */
export default Vue.extend({
	name:'ButtonGroup',
	props:{
		//下拉模式
		dropDown:Boolean,
		//按钮类型
		type:{
			type:String,
			default:'default',
			validator(v){
				return [
					'text',
					'default',
					'primary',
					'info',
					'success',
					'warning',
					'error',
				].indexOf(v)!==-1;
			},
		} as PropOptions<ButtonType>,
		//垂直模式
		vertical:Boolean,
		//线条模式
		outline:Boolean,
		//圆角
		rounded:Boolean,
		//分割模式
		split:Boolean,
		//选项
		options:{
			type:Array,
			default(){
				return [];
			}
		} as PropOptions<Array<PlainObject>>,
		//方法属性
		optionValue:{
			type:String,
			default:'value'
		},
		//显示属性
		optionLabel:{
			type:String,
			default:'label'
		},
		//禁用
		disable:Boolean,
		//split模式下, 禁止点击
		disableClick:Boolean,
		//下拉框绑定位置, 默认document.body
		appendTo:{
			type:[String,Element,Function],
			validator(v){
				if(typeof v==='string'){
					return v==='parent';
				}
				return true;
			}
		} as PropOptions<AppendTo>,
		//触发方式
		trigger:{
			type:String,
			default:'click',
			validator(v){
				return [
					'click',
					'mouseenter',
				].indexOf(v)!==-1;
			},
		} as PropOptions<triggerType>,
		//完全自定义按钮
		custom:Boolean,
	},
	data(){
		return {
			//组件宽度
			clientWidth:0,
			//是否聚焦按钮组
			focus:false,
			//触发元素
			triggerTarget:null as any,
		};
	},
	computed:{
		classes():string{
			return 'lexmis-ButtonGroup'+
				(this.dropDown
					?(
						' lexmis--dropDown'+
						(this.focus?' lexmis--focus':'')+
						(this.split?' lexmis--split':'')
					)
					:(
						(this.vertical?' lexmis--vertical':'')+
						(this.rounded?' lexmis--rounded':'')
					)
				);
		},
		//标准化后的选项
		transferOptions():Array<StandardOption>{
			if(this.dropDown){
				const {optionValue,optionLabel}=this;
				return this.options.map(function(option:PlainObject){
					const label=option[optionLabel];
					const method=option[optionValue];
					return {
						label:label,
						value:method,
						option,
					};
				});
			}
			return [];
		},
		//传给Tippy组件的属性
		tippyOptions():PlainObject|null{
			if(this.dropDown){
				const tippyOptions={
					advanced:true,
					head:false,
					disable:this.disable,
					appendTo:this.appendTo,
					width:0,
					minWidth:this.clientWidth,
					'tippy-options':{
						arrow:false,
						placement:'bottom',
						duration:[300,300],
						animation:'perspective',
						offset:[0,5],
						theme:'lexmis-widget',
						trigger:this.trigger,
						hideOnClick:this.trigger!=='mouseenter',
					} as Props
				};
				if(this.triggerTarget){
					tippyOptions['tippy-options'].triggerTarget=this.triggerTarget;
				}
				return tippyOptions;
			}
			return null;
		},
	},
	mounted(){
		this.$nextTick(function(){
			if(this.split){
				this.triggerTarget=(this.$refs.select as Vue).$el;
			}
		});
	},
	methods:{
		$_lexmis_show(){
			this.focus=true;
			this.clientWidth=this.$el.clientWidth;
		},
		$_lexmis_hide(){
			this.focus=false;
		},
	},
	render(h):VNode{
		const {default:slot,option:optionSlot}=this.$scopedSlots;
		if(this.tippyOptions){
			return h(Tippy,{
				ref:'Tippy',
				staticClass:'lexmis_ButtonGroup_Tippy',
				props:this.tippyOptions,
				on:{
					show:this.$_lexmis_show,
					hide:this.$_lexmis_hide,
				},
				scopedSlots:{
					content:() => h('div',{
						staticClass:'lexmis_ButtonGroup_options',
						staticStyle:{
							minWidth:this.clientWidth+'px',
						}
					},this.transferOptions.map((option,index) => {
						return h('div',{
							key:index,
							on:{
								click:() => {
									if(typeof option.value==='function'){
										option.value();
									}
									this.$emit('option-click',option);
									(this.$refs.Tippy as Tippy).hide();
								}
							}
						},optionSlot?optionSlot({option,index}):option.label);
					})),
					default:this.split
						?() => h('div',{
							staticClass:this.classes,
						},[
							h(Button,{
								staticClass:'lexmis_ButtonPart',
								props:{
									type:this.type,
									outline:this.outline,
									rounded:this.rounded,
									disable:this.disableClick,
								},
								on:{
									click:() => {
										this.$emit('click');
									}
								}
							},slot&&slot(undefined)),
							h(Button,{
								ref:'select',
								staticClass:'lexmis_selectPart',
								props:{
									type:this.type,
									outline:this.outline,
									rounded:this.rounded,
									disable:this.disable,
								},
							},[
								h(Icon,{
									staticClass:'lexmis_arrow',
									props:{
										name:'play_arrow'
									}
								})
							]),
						])
						:!this.custom
							?() => h(Button,{
								staticClass:this.classes,
								props:{
									type:this.type,
									outline:this.outline,
									rounded:this.rounded,
									disable:this.disable,
								},
								on:{
									click:(Keyboard:boolean) => {
										if(Keyboard){
											if(this.focus){
												(this.$refs.Tippy as Tippy).hide();
											}else{
												(this.$refs.Tippy as Tippy).show();
											}
										}
									}
								}
							},[
								slot&&slot(undefined),
								h(Icon,{
									staticClass:'lexmis_arrow',
									props:{
										name:'play_arrow'
									}
								})
							])
							:slot,
				},
			});
		}else{
			return h('div',{
				staticClass:this.classes,
			},slot&&slot(undefined));
		}
	},
});
